package com.share.finance.risk.third.service.impl;

import com.alibaba.fastjson.JSON;
import com.share.finance.risk.common.model.constant.SysConf;
import com.share.finance.risk.common.model.sys.LocalRequest;
import com.share.finance.risk.common.model.sys.ThirdRequest;
import com.share.finance.risk.third.aop.CacheApiData;
import com.share.finance.risk.third.model.db.InterfaceConfig;
import com.share.finance.risk.third.model.db.LocalVariateConf;
import com.share.finance.risk.third.service.AsyncDealService;
import com.share.finance.risk.third.service.MainService;
import com.share.finance.risk.third.service.IInterfaceConfigService;
import com.share.finance.risk.third.service.ILocalVariateConfService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

@Slf4j
@Service
public class MainServiceImpl implements MainService {
    @Autowired
    private CacheApiData cacheApiData;
    @Autowired
    private AsyncDealService asyncDealService;

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private IInterfaceConfigService interfaceConfigService;

    @Autowired
    private ILocalVariateConfService localVariateConfService;

    /**
     * 三方接口
     *
     * @param requestData
     * @return
     */
    @Override
    public Map<String, Object> info(ThirdRequest requestData) throws Exception {
        Map<String, Object> returnJsonMap = new ConcurrentHashMap<>();
        String param = JSON.toJSONString(requestData);
        Set<String> intIdSet = Arrays.stream(requestData.getIntIds().split(",")).collect(Collectors.toSet());
        if (CollectionUtils.isEmpty(intIdSet)) {
            log.info("本次请求intIds为空");
            return returnJsonMap;
        }

        //接收异步future
        List<CompletableFuture<Void>> futureList = new LinkedList<>();
        for (String intId : intIdSet) {
            InterfaceConfig interfaceConfig = interfaceConfigService.getInterfaceConfig(intId);
            ThirdRequest intParam = JSON.parseObject(param, ThirdRequest.class);
            intParam.setIntId(intId);//塞一个值

            CompletableFuture<Void> futureTmp = CompletableFuture.supplyAsync(() -> {
                Object bean = applicationContext.getBean(interfaceConfig.getIntClass());
                Object invoke = null;
                try {
                    invoke = bean.getClass().getMethod(interfaceConfig.getIntMethod(), ThirdRequest.class).invoke(bean, intParam);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return invoke == null ? "empty" : invoke.toString();
            }).exceptionally(e -> {
                log.error("IntMethod()", e);
                return "exception";
            }).thenAccept(v -> {
                //执行成功 将返回的json内容解析并入库
                returnJsonMap.put(interfaceConfig.getIntId(), v);
            });

            futureList.add(futureTmp);
        }

        //阻塞等待结果,futureList元素可以为0个
        CompletableFuture.allOf(futureList.toArray(new CompletableFuture[futureList.size()])).get();
        return returnJsonMap;
    }


    /**
     * http的接口调用改为使用grooxy包装然后再调用
     *
     * @param requestData
     * @return
     */
    public Map<String, Object> channle(ThirdRequest requestData) throws Exception {
        Map<String, Object> returnJsonMap = new ConcurrentHashMap<>();
        String param = JSON.toJSONString(requestData);
        Set<String> intIdSet = Arrays.stream(requestData.getIntIds().split(",")).collect(Collectors.toSet());
        if (CollectionUtils.isEmpty(intIdSet)) {
            log.info("本次请求intIds为空");
            return returnJsonMap;
        }

        //接收异步future
        List<CompletableFuture<Void>> futureList = new LinkedList<>();
        for (String intId : intIdSet) {
            InterfaceConfig interfaceConfig = interfaceConfigService.getInterfaceConfig(intId);
            ThirdRequest intParam = JSON.parseObject(param, ThirdRequest.class);
            intParam.setIntId(intId);//塞一个值
            String jsonIntParam = JSON.toJSONString(intParam);

            CompletableFuture<Void> futureTmp = CompletableFuture.supplyAsync(() -> {
                String reValue = null;
                long startTime = System.currentTimeMillis();
                //1.从缓存中获取数据
                String cacheData = cacheApiData.getDataFromCache(intParam, interfaceConfig);

                //2.触发调用groovy
                if (StringUtils.isBlank(cacheData)) {
                    Object reTmp = interfaceConfigService.exeGroovyScript(intId, SysConf.GROOVY_METHOD, jsonIntParam);
                    reValue = (reTmp == null) ? "empty" : reTmp.toString();


                    //3.设置缓存
                    cacheApiData.setDataToCache(intParam, interfaceConfig, cacheData);
                }

                //4.记录日志
                asyncDealService.channelRequestLogServiceSaveLog(interfaceConfig, intParam, jsonIntParam, reValue, StringUtils.isNotBlank(cacheData), System.currentTimeMillis() - startTime);

                return reValue;
            }).exceptionally(e -> {
                log.error("IntMethod()", e);
                return "exception";
            }).thenAccept(v -> {
                //执行成功 将返回的json内容解析并入库
                returnJsonMap.put(interfaceConfig.getIntId(), v);
            });

            futureList.add(futureTmp);
        }

        //阻塞等待结果,futureList元素可以为0个
        CompletableFuture.allOf(futureList.toArray(new CompletableFuture[futureList.size()])).get();
        return returnJsonMap;
    }


    /**
     * 本地变量
     *
     * @param requestData
     * @return
     */
    @Override
    public Map<String, Object> local(LocalRequest requestData) throws Exception {
        Map<String, Object> returnJsonMap = new ConcurrentHashMap<>();
        List<String> fieldIds = requestData.getFieldList();
        String param = JSON.toJSONString(requestData);
        if (CollectionUtils.isEmpty(fieldIds)) {
            log.info("本次请求fieldIds为空");
            return returnJsonMap;
        }

        //接收异步future
        List<CompletableFuture<Void>> futureList = new LinkedList<>();
        for (String fieldId : fieldIds) {
            LocalVariateConf config = localVariateConfService.getByFieldId(fieldId);
            if (config == null) {
                log.info("本地不存在config={}", JSON.toJSONString(config));
                continue;
            }
            LocalRequest intParam = JSON.parseObject(param, LocalRequest.class);
            intParam.setFieldId(fieldId);//塞一个值

            CompletableFuture<Void> futureTmp = CompletableFuture.supplyAsync(() -> {
                Object bean = applicationContext.getBean(config.getIntClass());
                Map<String, Object> invoke = null;
                try {
                    invoke = (Map<String, Object>) bean.getClass().getMethod(config.getIntMethod(), LocalRequest.class).invoke(bean, intParam);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return invoke == null ? new HashMap<String, Object>() : invoke;
            }).exceptionally(e -> {
                log.error("local-IntMethod()", e);
                return new HashMap<String, Object>();
            }).thenAccept(v -> {
                //执行成功 将返回的json内容解析并入库
                returnJsonMap.putAll(v);
            });

            futureList.add(futureTmp);
        }

        //阻塞等待结果,futureList元素可以为0个
        CompletableFuture.allOf(futureList.toArray(new CompletableFuture[futureList.size()])).get();
        return returnJsonMap;
    }
}
